#!/usr/bin/python  # 指定解释器为 Python
# -*- coding: UTF-8 -*-  # 指定源文件编码为 UTF-8，保证中文注释正常
#  语音听写（即时语音识别）：用于1分钟内的即时语音转文字技术，支持实时返回识别结果，  # 模块功能说明
#  达到一边上传音频一边获得识别文本的效果。  # 进一步说明应用场景
from datetime import datetime  # 导入 datetime 用于记录识别时间
from stt_realtime_api_helper import stt_api_get_result  # 导入语音听写模块中的主调用函数

# FastAPI/Starlette 相关依赖  # 以下为 Web 框架相关导入
from fastapi import FastAPI, Request, UploadFile, File  # 导入 FastAPI 核心类与请求、文件类型
from fastapi.responses import HTMLResponse, JSONResponse  # 导入 HTML 与 JSON 响应类型
from fastapi.staticfiles import StaticFiles  # 导入静态文件挂载支持
from fastapi.templating import Jinja2Templates  # 导入模板渲染支持

# 讯飞开放平台相关信息  # 配置调用讯飞语音听写所需的凭证与文件路径
APPID = 'da319dbd'  # 到控制台语音听写页面获取 APPID
APIKey = 'd9369991ff66b75dcf0ca7dfafc311a4'  # 到控制台语音听写页面获取 APIKey
APISecret = 'OGExYzk4MjhjZWNkMzMwNGM3ZmIwMTJk'  # 注意不要与 APIKey 写反的 APISecret
text_file = './data.txt'  # 用于存储听写后的文本（最终结果会被写入）
text_history = './history.txt'  # 用于存储听写的历史记录（包含时间戳与文本）

app = FastAPI()  # 创建 FastAPI 应用实例
app.mount("/static", StaticFiles(directory="static"), name="static")  # 挂载静态资源目录到 /static
templates = Jinja2Templates(directory="templates")  # 指定模板目录以供渲染


@app.get("/", response_class=HTMLResponse)  # 注册 GET / 路由，返回 HTML 页面
async def speech_to_text_page(request: Request):  # 定义异步处理函数，接收 Request 对象
    # 渲染首页模板，初始化结果为空  # 模板上下文中传入空的 result 以避免页面错误
    return templates.TemplateResponse("home.html", {"request": request, "result": {}})  # 返回首页


@app.post("/", response_class=HTMLResponse)  # 注册 POST / 路由，处理文件上传并显示结果
async def speech_to_text_upload(request: Request, file: UploadFile = File(None)):  # 接收上传的文件
    # 如果没有上传文件，返回空结果  # 防御式处理，避免 None 引发异常
    if file is None:  # 判断是否传入文件
        return templates.TemplateResponse("home.html", {"request": request, "result": {}})  # 返回首页

    filename = file.filename  # 获取原始文件名
    # 保存上传的文件到磁盘  # 将上传内容写入本地，以便后续识别模块读取
    content = await file.read()  # 异步读取文件内容为字节
    with open(filename, "wb") as out_file:  # 以二进制写方式打开目标文件
        out_file.write(content)  # 写入文件内容

    # 调用听写模块并将结果保存到txt文件中  # 调用封装的识别函数，输出至 data.txt
    stt_api_get_result(APPID, APIKey, APISecret, filename)  # 传入凭证与文件名进行识别

    # 读取txt文件内容获取听写结果，并写入历史记录  # 识别完成后，聚合结果并记录历史
    with open(text_file, 'r', encoding='utf-8') as f:  # 打开结果文件以读取
        text = f.readlines()  # 读取所有行（可能多次写入）
        with open(text_history, 'a', encoding='utf-8') as f1:  # 追加写入历史记录
            current_datetime = datetime.now()  # 获取当前时间戳
            f1.write('date: ' + str(current_datetime) + '\t' + str(text) + '\n')  # 历史记录一行

    result = ''.join(text)  # 将行数组拼接成完整文本
    # 渲染模板并返回听写结果  # 将识别结果呈现到页面右侧
    return templates.TemplateResponse("home.html", {"request": request, "result": result})  # 返回渲染后的页面


@app.post("/mic")  # 注册 POST /mic 路由，处理麦克风录音上传
async def speech_to_text_mic_upload(file: UploadFile = File(...)):  # 接收前端录音生成的文件
    # 处理前端麦克风录音上传，返回JSON文本结果  # 与文件上传逻辑类似，但返回 JSON
    filename = file.filename  # 录音文件名（前端命名为 recording.wav）
    content = await file.read()  # 读取录音内容
    with open(filename, "wb") as out_file:  # 保存到磁盘
        out_file.write(content)  # 写入文件

    # 调用听写模块  # 进行语音识别
    stt_api_get_result(APPID, APIKey, APISecret, filename)  # 调用识别函数

    # 读取结果文本并记录历史  # 与上传文件一致，统一写入历史
    with open(text_file, 'r', encoding='utf-8') as f:  # 读取识别结果
        text = f.readlines()  # 获取所有行
        with open(text_history, 'a', encoding='utf-8') as f1:  # 写入历史
            current_datetime = datetime.now()  # 当前时间
            f1.write('date: ' + str(current_datetime) + '\t' + str(text) + '\n')  # 写一条历史记录

    result = ''.join(text)  # 拼接识别结果文本
    return JSONResponse({"result": result})  # 以 JSON 形式返回给前端


if __name__ == "__main__":  # 作为脚本运行时入口
    import uvicorn  # 导入 uvicorn 服务器
    uvicorn.run("speech_to_text_realtime_app:app", host="127.0.0.1", port=8001, reload=True)  # 启动服务并开启热重载
